package com.fpswork.util;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.StringConverter;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;

import com.fpswork.core.exception.exception.BusinessException;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * 1、标准javaBean的处理，必须是属性都有get,set方法
 */
public class BeanUtils  {
  
	static {
		// 在封装之前 注册转换器
		ConvertUtils.register(new DateLocaleConverter(), Date.class);
		ConvertUtils.register(new StringConverter(), String.class);
	}
  
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static  void copyProperties(Object toObject,Object fromObject) throws BusinessException{
		try {

			if(toObject== null){
				throw new BusinessException("copyProperties函数错误，toObject不可为空！");
			}
			if(fromObject==null){
				throw new BusinessException("copyProperties函数错误，fromObject不可为空！");
			}
			Class fromObjectClass = fromObject.getClass();
			Class toObjectClass = toObject.getClass();
			if(toObjectClass.isAssignableFrom(fromObjectClass)){
				org.springframework.beans.BeanUtils.copyProperties( fromObject,toObject);
			}else{
				org.apache.commons.beanutils.BeanUtils.copyProperties(toObject,fromObject);
			}
			//org.apache.commons.beanutils.BeanUtils.copyProperties(toObject,fromObject);
		} catch (Exception e) {
			throw new BusinessException(e);
		}
	}





	/**
	 * 按资源对象复制成目标对象
	 * 返回目标类的对象
	 * @param <T> 目标对象类型参数
	 * @param source 源对象
	 * @param destType 目标对象类型
	 * @return
	 */
	public static <T> T copyAs(Object source, Class<T> destType)  throws BusinessException{

		if (source == null) {
			return null;
		}
		try {
			T dest = destType.newInstance();
			copyProperties(dest, source) ;
			return  dest;
		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 复制源对象集合到目标对象列表
	 * 
	 * @param <T>
	 * @param source
	 * @param destType
	 * @return
	 */
	public static <T> List<T> copyAs(Collection<?> source, Class<T> destType) throws BusinessException{
		if (source == null) {
			return null;
		}
		ArrayList<T> result = new ArrayList<T>();
		for (Object object : source) {
			result.add(copyAs(object, destType));
		}
		return result;
	}

	/**
	 * 根据对象和对象需要复制的属性值得，获取不需要复制的属性
	 * @param obj
	 * @param copyPropertiesList
     * @return
     */
	private static String[] getIgnoreProperties(Object obj, List<String> copyPropertiesList){
		String[] ignorePropertiesArr=null;
		PropertyDescriptor[] objPds =  org.springframework.beans.BeanUtils.getPropertyDescriptors(obj.getClass());
		List<String> ignorePropertiesList = new ArrayList<String>();

		for(PropertyDescriptor objPd:objPds){
			if(objPd.getWriteMethod() != null && (copyPropertiesList!=null&&!copyPropertiesList.isEmpty())&& !copyPropertiesList.contains(objPd.getName())) {
				ignorePropertiesList.add(objPd.getName());
			}
		}

		if(  ignorePropertiesList!=null&&!ignorePropertiesList.isEmpty() ){
			int size= ignorePropertiesList.size();
			ignorePropertiesArr = ignorePropertiesList.toArray(new String[size]);
		}
		return ignorePropertiesArr;
	}

	/**
	 * 根据提供的源对象，和目标对象需要复制的属性List,复制部分属性
	 * 注意：
	 * 如果目标对象的属性，超过源对象的部分会被处理成null值
	 * @param source
	 * @param target
	 * @param copyPropertiesList
     */
	public static void copyPartProperties(Object source, Object target, List<String> copyPropertiesList ){
		String[] arr = getIgnoreProperties(target,copyPropertiesList);
		org.springframework.beans.BeanUtils.copyProperties(source,target,arr);
	}
	
	
	
}
